package cn.mdmbct.douyin.basis.service.interfaces;

import cn.mdmbct.douyin.basis.body.video.*;
import cn.mdmbct.douyin.basis.response.video.*;
import cn.mdmbct.douyin.basis.service.executor.VideoManagerServiceProvider;
import cn.mdmbct.douyin.common.bean.PageCount;
import cn.mdmbct.douyin.common.enums.ApiPlatform;
import cn.mdmbct.douyin.common.enums.MethodType;
import cn.mdmbct.douyin.common.exception.ApiCallException;
import cn.mdmbct.douyin.common.proxy.annotations.Mapping;
import cn.mdmbct.douyin.common.proxy.annotations.Provider;
import cn.mdmbct.douyin.common.proxy.annotations.RequestBody;
import cn.mdmbct.douyin.common.proxy.annotations.RequestParam;
import cn.mdmbct.douyin.common.response.DefaultResponseData;
import cn.mdmbct.douyin.common.session.DySession;

import java.io.File;
import java.io.FileNotFoundException;

/**
 * <a href="https://open.douyin.com/platform/doc/6848798087398295555">视频管理API接口</a>
 * <p>
 * 支持抖音、头条、西瓜<p>
 * platform参数用来控制平台
 *
 * @author mdmbct  mdmbct@outlook.com
 * @date 2021/3/9 11:16
 * @modified mdmbct
 * @since 1.0
 */
public interface VideoManagerService {

    /**
     * 最大单个视频文件 128MB
     */
    int MAX_SINGLE_VIDEO_FILE_SIZE = 128 * 1024 * 1024;

    /**
     * 默认单个分片视频文件大小20MB
     */
    int DEFAULT_PART_VIDEO_FILE_SIZE = 20 * 1024 * 1024;

    /**
     * 最小单个分片视频文件大小5MB
     */
    int MIN_PART_VIDEO_FILE_SIZE = 5 * 1024 * 1024;

    /**
     * 允许的视频文件大小最大为4GB
     */
    long MAX_ALLOW_VIDEO_FILE_SIZE = 4L * 1024 * 1024 * 1024;

    /**
     * 图片最大不超过100MB
     */
    int MAX_ALLOW_IMAGE_SIZE = 100 * 1024 * 1024;

    /**
     * <a href="https://open.douyin.com/platform/doc/6848798087398295555">上传视频到文件服务器</a>
     * <p>
     * Scope: `video.create`需要申请权限需要用户授权
     * <p>
     * 该接口用于上传视频文件到文件服务器，获取视频文件video_id。该接口适用于抖音。
     * <p>
     * 注意：
     * <p>
     * 抖音的OAuth API以https://open.douyin.com/开头。
     * <p>
     * 超过50m的视频建议采用分片上传，可以降低网关超时造成的失败。超过128m的视频必须采用分片上传。视频总大小4GB以内。单个分片建议20MB，最小5MB。
     * <p>
     * 视频文件要求：
     * <p>
     * 为了更好的观看体验，推荐上传16:9，分辨率为720p（1280x720）及以上的竖版视频。
     * <p>
     * 支持常用视频格式，推荐使用 mp4 、webm。
     * <p>
     * 视频文件大小不超过128M，时长在15分钟以内。
     * <p>
     * 带品牌logo或品牌水印的视频，会命中抖音的审核逻辑，有比较大的概率导致分享视频推荐降权处理/分享视频下架处理/分享账号被封禁处理。强烈建议第三方应用自行处理好分享内容中的不合规水印。
     * <p>
     * 视频审核逻辑与端上一致。
     *
     * @param openId    open id
     * @param videoFile 不超过128MB的视频文件
     * @param platform  平台
     * @return {@link VideoUploadRes.VideoUploadResponseData}
     * @throws ApiCallException api调用异常
     */
    @Provider(VideoManagerServiceProvider.class)
    @Mapping(value = "/video/upload", method = MethodType.POST)
    VideoUploadRes.VideoUploadResponseData videoUpload(@RequestParam("open_id") String openId,
                                                       File videoFile,
                                                       ApiPlatform platform) throws ApiCallException;

    /**
     * <a href="https://open.douyin.com/platform/doc/6848798087398393859">分片初始化上传</a>
     * <p>
     * Scope: `video.create`需要申请权限需要用户授权
     * <p>
     * 该接口用于分片上传视频文件到文件服务器，先初始化上传获取upload_id。该接口适用于抖音。
     * <p>
     * 注意：
     * <p>
     * 抖音的OAuth API以https://open.douyin.com/开头。
     * <p>
     * 超过50m的视频建议采用分片上传，可以降低网关超时造成的失败。超过128m的视频必须采用分片上传。视频总大小4GB以内。单个分片建议20MB，最小5MB。
     * <p>
     * 视频文件要求：
     * <p>
     * 为了更好的观看体验，推荐上传16:9，分辨率为720p（1280x720）及以上的竖版视频。
     * <p>
     * 支持常用视频格式，推荐使用 mp4 、webm。
     * <p>
     * 带品牌logo或品牌水印的视频，会命中抖音的审核逻辑，有比较大的概率导致分享视频推荐降权处理/分享视频下架处理/分享账号被封禁处理。强烈建议第三方应用自行处理好分享内容中的不合规水印。
     * <p>
     * 视频审核逻辑与端上一致。
     *
     * @param openId   open id
     * @param platform 平台
     * @return {@link VideoPartInitRes.VideoPartInitResData}
     * @throws ApiCallException api调用异常
     */
    @Mapping(value = "/video/part/init", method = MethodType.POST)
    VideoPartInitRes.VideoPartInitResData videoPartInit(@RequestParam("open_id") String openId,
                                                        ApiPlatform platform) throws ApiCallException;

    /**
     * <a href="https://open.douyin.com/platform/doc/6848798087226460172">上传视频分片到文件服务器</a>
     * <p>
     * Scope: `video.create`需要申请权限需要用户授权
     * <p>
     * 该接口用于分片上传视频文件到文件服务器，上传阶段。该接口适用于抖音。
     * <p>
     * 注意：
     * <p>
     * 抖音的OAuth API以https://open.douyin.com/开头。
     * <p>
     * 超过50m的视频建议采用分片上传，可以降低网关超时造成的失败。超过128m的视频必须采用分片上传。视频总大小4GB以内。单个分片建议20MB，最小5MB。
     * <p>
     * 注意参数中upload_id作为url参数时，必须encode，只对upload_id进行encode
     * <p>
     * 视频文件要求：
     * <p>
     * 为了更好的观看体验，推荐上传16:9，分辨率为720p（1280x720）及以上的竖版视频。
     * <p>
     * 支持常用视频格式，推荐使用 mp4 、webm。
     * <p>
     * 带品牌logo或品牌水印的视频，会命中抖音的审核逻辑，有比较大的概率导致分享视频推荐降权处理/分享视频下架处理/分享账号被封禁处理。强烈建议第三方应用自行处理好分享内容中的不合规水印。
     * <p>
     * 视频审核逻辑与端上一致。
     *
     * @param openId     open id
     * @param uploadId   分片上传的标记。有限时间为2小时。
     * @param partNumber 表示该分片在整个视频内的相对位置，从1开始（1即表示第一段视频分片）。
     * @param partVideo  视频分片数据
     * @param videoFile  视频文件
     * @param platform   平台
     * @return {@link DefaultResponseData}
     * @throws ApiCallException api调用异常
     */
    @Provider(VideoManagerServiceProvider.class)
    @Mapping(value = "/video/part/upload", method = MethodType.POST)
    DefaultResponseData videoPartUpload(@RequestParam("open_id") String openId,
                                        @RequestParam("upload_id") String uploadId,
                                        @RequestParam("part_number") int partNumber,
                                        @RequestBody VideoUploadReqBody partVideo,
                                        File videoFile,
                                        ApiPlatform platform) throws ApiCallException;

    /**
     * <a href="https://open.douyin.com/platform/doc/6848798087398361091">分片完成上传</a>
     * <p>
     * Scope: `video.create`需要申请权限需要用户授权
     * <p>
     * 该接口用于分片上传视频文件到文件服务器，完成上传。该接口适用于抖音。
     * <p>
     * 注意：
     * <p>
     * 抖音的OAuth API以https://open.douyin.com/开头。
     * <p>
     * 超过50m的视频建议采用分片上传，可以降低网关超时造成的失败。超过128m的视频必须采用分片上传。视频总大小4GB以内。单个分片建议20MB，最小5MB。
     * <p>
     * 视频文件要求：
     * <p>
     * 为了更好的观看体验，推荐上传16:9，分辨率为720p（1280x720）及以上的竖版视频。
     * <p>
     * 支持常用视频格式，推荐使用 mp4 、webm。
     * <p>
     * 带品牌logo或品牌水印的视频，会命中抖音的审核逻辑，有比较大的概率导致分享视频推荐降权处理/分享视频下架处理/分享账号被封禁处理。强烈建议第三方应用自行处理好分享内容中的不合规水印。
     * <p>
     * 视频审核逻辑与端上一致。
     *
     * @param openId   open id
     * @param uploadId 分片上传的标记。有限时间为2小时。
     * @param platform 平台
     * @return {@link VideoUploadRes.VideoUploadResponseData}
     * @throws ApiCallException api调用异常
     */
    @Mapping(value = "/video/part/complete", method = MethodType.POST)
    VideoUploadRes.VideoUploadResponseData videoPartComplete(@RequestParam("open_id") String openId,
                                                             @RequestParam("upload_id") String uploadId,
                                                             ApiPlatform platform) throws ApiCallException;

    /**
     * <a href="https://open.douyin.com/platform/doc/6848798087398328323">创建抖音视频</a>
     * <p>
     * Scope: `video.create`需要申请权限需要用户授权
     * <p>
     * 该接口用于创建抖音视频（支持话题, 小程序等功能）。该接口适用于抖音。
     * <p>
     * 注意：
     * <p>
     * 抖音的OAuth API以https://open.douyin.com/开头。
     * <p>
     * 挂载小程序请先完成申请->申请及使用说明
     * <p>
     * 创建抖音视频后, 会有一个审核过程, 期间只有自己可见。
     * <p>
     * 如果发布视频想@用户，需要获取昵称与open_id。
     * <p>
     * 目前发布视频接口，支持三种锚点类型，包括：小程序、游戏、poi。不支持携带多种类型的锚点。
     * <p>
     * 如需代用户创建视频，除授权外，每次调用都需要在产品设计中让用户明确感知相关操作。如发现未经用户感知代用户创建视频，或将回收相关接口权限并处罚应用及账号。
     *
     * @param openId   open id
     * @param body     创建视频请求体
     * @param platform 平台
     * @return {@link VideoCreateRes.VideoCreateResData}
     * @throws ApiCallException api调用异常
     */
    @Mapping(value = "/video/create", method = MethodType.POST)
    VideoCreateRes.VideoCreateResData videoCreate(@RequestParam("open_id") String openId,
                                                  @RequestBody VideoCreateReqBody body,
                                                  ApiPlatform platform) throws ApiCallException;

    /**
     * <a href="https://open.douyin.com/platform/doc/6848806536383383560">删除授权用户发布的视频</a>
     * <p>
     * scope：'video.delete'需要申请权限需要用户授权
     * <p>
     * 该接口用于删除授权用户该抖音账号下的视频。该接口适用于抖音。
     * <p>
     * 注意：
     * <p>
     * 抖音的OAuth API以https://open.douyin.com/开头。
     * <p>
     * 可以删除已授权用户自己发布的视频。
     * <p>
     * 删除的视频无法恢复，请谨慎操作！
     *
     * @param openId   open id
     * @param itemId   视频id
     * @param platform 平台
     * @return {@link DefaultResponseData}
     * @throws ApiCallException api调用异常
     */
    @Mapping(value = "/video/delete", method = MethodType.POST)
    DefaultResponseData videoDelete(@RequestParam("open_id") String openId,
                                    @RequestParam("item_id") String itemId,
                                    ApiPlatform platform) throws ApiCallException;

    /**
     * 自动上传视频 根据视频大小自动决定是否分片上传
     *
     * @param openId         open id
     * @param videoFile      视频文件
     * @param platform       平台
     * @param storageManager 存储管理器{@link DySession} 使用自动配置的话 可以直接从IOC中获取
     * @return {@link VideoUploadRes.VideoUploadResponseData}
     * @throws FileNotFoundException 视频文件不存在
     * @throws ApiCallException      api调用异常
     */
    @Provider(VideoManagerServiceProvider.class)
    VideoUploadRes.VideoUploadResponseData autoUploadVideo(String openId,
                                                           File videoFile,
                                                           ApiPlatform platform,
                                                           DySession storageManager)
            throws ApiCallException, FileNotFoundException;

    /**
     * 自动上传视频 根据视频大小自动决定是否分片上传 上传完成后自动创建视频
     *
     * @param openId         open id
     * @param videoFile      视频文件
     * @param param          自动上传视频并创建 的参数
     * @param platform       平台
     * @param storageManager 存储管理器{@link DySession} 使用自动配置的话 可以直接从IOC中获取
     * @return {@link VideoCreateRes.VideoCreateResData}
     * @throws FileNotFoundException 视频文件不存在
     * @throws ApiCallException      api调用异常
     */
    @Provider(VideoManagerServiceProvider.class)
    VideoCreateRes.VideoCreateResData autoCreateVideo(String openId,
                                                      File videoFile,
                                                      AutoCreateVideoParam param,
                                                      ApiPlatform platform,
                                                      DySession storageManager)
            throws ApiCallException, FileNotFoundException;

    /**
     * <a href="https://open.douyin.com/platform/doc/6848806536383318024">询授权账号视频数据</a>查
     * <p>
     * Scope：'video.list'需要用户授权需要申请权限
     * <p>
     * 该接口用于分页获取用户所有视频的数据，返回的数据是实时的。该接口适用于抖音。
     * <p>
     * 注意：
     * <p>
     * 抖音的OAuth API以https://open.douyin.com/开头。
     *
     * @param openId   open id
     * @param cursor   分页游标, 第一页请求cursor是0, response中会返回下一页请求用到的cursor, 同时response还会返回has_more来表明是否有更多的数据。
     * @param count    每页数量
     * @param platform 平台
     * @return {@link VideoListRes.VideoListResData}
     * @throws ApiCallException api调用异常
     */
    @Mapping("/video/list")
    VideoListRes.VideoListResData getVideoList(@RequestParam("open_id") String openId,
                                               @RequestParam long cursor,
                                               @RequestParam PageCount count,
                                               ApiPlatform platform) throws ApiCallException;


    /**
     * <a href="https://open.douyin.com/platform/doc/6848806544931325965">查询指定视频数据</a>
     * <p>
     * Scope: `video.data`需要用户授权需要申请权限
     * <p>
     * 该接口 用于查询用户特定视频的数据, 如点赞数, 播放数等，返回的数据是实时的。该接口适用于抖音。
     * <p>
     * 注意：
     * <p>
     * 抖音的OAuth API以https://open.douyin.com/开头。
     * <p>
     * 有两种方式获取item_id(抖音视频id):
     * <p>
     * 查询视频分享结果和数据;
     * <p>
     * <a href="https://open.douyin.com/platform/doc/6848798087398328323">发布抖音视频</a>
     *
     * @param openId   open id
     * @param body     item_id数组，仅能查询access_token对应用户上传的视频
     * @param platform 平台
     * @return {@link VideoListRes.VideoListResData}
     * @throws ApiCallException api调用异常
     */
    @Mapping(value = "/video/data", method = MethodType.POST)
    VideoListRes.VideoListResData getVideoData(@RequestParam("open_id") String openId,
                                               @RequestBody VideoDataReqBody body,
                                               ApiPlatform platform) throws ApiCallException;

    /**
     * <a href="https://open.douyin.com/platform/doc/6848798622172121099">查询视频分享结果及数据获取share-id</a>
     * <p>
     * Scope: `aweme.share`不需要用户授权
     * <p>
     * 该接口用获取share_id；该接口适用于抖音。
     * <p>
     * share_id 可以用于：
     * <p>
     * 追踪分享的视频是否成功。
     * <p>
     * 获取分享视频的数据,如点赞数, 评论数等。
     * <p>
     * 接入步骤：
     * <p>
     * 去http://open.douyin.com/platform/business申请发布视频的能力。
     * <p>
     * 分享前获取标识单次分享的share_id。
     * <p>
     * 调用分享sdk时传入share_id。
     * <p>
     * 基于Webhooks接收分享成功的回调信息
     * <p>
     * item_id可用于查询<a href="https://open.douyin.com/platform/doc/6848806544931325965">视频数据</a>。
     *
     * @param openId         open id
     * @param needCallback   如果需要知道视频分享成功的结果，need_callback设置为true
     * @param sourceStyleId  多来源样式id（暂未开放）
     * @param defaultHashtag 追踪分享默认hashtag
     * @param linkParam      分享来源url附加参数（暂未开放）
     * @return {@link VideoShareDataRes.VideoShareDataResData}
     * @throws ApiCallException api调用异常
     */
    @Mapping("/share-id/")
    VideoShareDataRes.VideoShareDataResData getVideoShareId(@RequestParam("open_id") String openId,
                                                            @RequestParam("need_callback") boolean needCallback,
                                                            @RequestParam("source_style_id") String sourceStyleId,
                                                            @RequestParam("default_hashtag") String defaultHashtag,
                                                            @RequestParam("link_param") String linkParam) throws ApiCallException;


    /**
     * <a href="https://open.douyin.com/platform/doc/6848798493293807628">上传图片到文件服务器</a>
     * <p>
     * Scope: `video.create`需要申请权限需要用户授权
     * 该接口用于上传图片到文件服务器，得到图片的唯一标志image_id。该接口适用于抖音。
     * <p>
     * 注意：
     * <p>
     * 抖音的OAuth API以https://open.douyin.com/开头。<p>
     * 图片文件要求：
     * <p>
     * 图片大小不超过100M。<p>
     * 强烈建议自行处理好分享内容中的不合规水印<p>
     * 图片审核逻辑与端上一致。
     *
     * @param openId    open id
     * @param imageFile 小于100MB的图片文件
     * @return {@link ImageUploadRes.ImageUploadResData}
     * @throws ApiCallException api调用异常
     */
    @Provider(VideoManagerServiceProvider.class)
    ImageUploadRes.ImageUploadResData imageUpload(@RequestParam("open_id") String openId,
                                                  @RequestBody File imageFile) throws ApiCallException;

    /**
     * <a href="https://open.douyin.com/platform/doc/6848798493293774860">发布图片</a>
     * Scope: `video.create`需要申请权限需要用户授权<p>
     * 该接口用于发布图片抖音（支持话题，小程序等功能）；该接口适用于抖音。<p>
     * <p>
     * 注意：
     * <p>
     * 抖音的OAuth API以https://open.douyin.com/开头。<p>
     * 调用/image/create/发布图片到抖音。会有一个审核过程，期间只有自己可见。<p>
     *
     * @param openId open id
     * @param body   创建图片请求体
     * @return {@link VideoCreateRes.VideoCreateResData}
     * @throws ApiCallException api调用异常
     */
    @Mapping(value = "/image/create", method = MethodType.POST)
    VideoCreateRes.VideoCreateResData imageCreate(@RequestParam("open_id") String openId,
                                                  @RequestBody ImageCreateBody body) throws ApiCallException;

    /**
     * 自动上传并创建图片
     *
     * @param openId               open id
     * @param imageFile            图片文件
     * @param autoCreateImageParam 自动创建图片参数
     * @return {@link VideoCreateRes.VideoCreateResData}
     * @throws ApiCallException api调用异常
     */
    @Provider(value = VideoManagerServiceProvider.class, addApiParam = false)
    VideoCreateRes.VideoCreateResData autoCreateImage(String openId, File imageFile, AutoCreateImageParam autoCreateImageParam) throws ApiCallException;
}
